package org.fast.project.dao.function;

import org.hibernate.bytecode.enhance.spi.LazyPropertyInitializer;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.event.internal.DefaultMergeEventListener;
import org.hibernate.event.spi.MergeContext;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.property.access.internal.PropertyAccessStrategyBackRefImpl;
import org.hibernate.type.Type;


/**
 * 忽略 Null 值更新事件侦听器
 *
 * @author D·jun
 * @date 2024/10/24
 */
public class IgnoreNullValueUpdateEventListener extends DefaultMergeEventListener {
    public static final IgnoreNullValueUpdateEventListener INSTANCE = new IgnoreNullValueUpdateEventListener();

    @Override
    protected void copyValues(final EntityPersister persister, final Object entity, final Object target,
        final SessionImplementor source, final MergeContext copyCache) {
        //源目标
        Object[] original = persister.getValues(entity);
        //存储目标
        Object[] targets = persister.getValues(target);

        Type[] types = persister.getPropertyTypes();

        Object[] copied = new Object[original.length];
        for (int i = 0; i < types.length; i++) {
            if (original[i] == null || original[i] == LazyPropertyInitializer.UNFETCHED_PROPERTY
                || original[i] == PropertyAccessStrategyBackRefImpl.UNKNOWN) {
                copied[i] = targets[i];
            } else {
                copied[i] = types[i].replace(original[i], targets[i], source, target, copyCache);
            }
        }

        persister.setValues(target, copied);
    }
}